﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Security.Cryptography;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using Debug = UnityEngine.Debug;

public static class ToolUnity
{
    // 缓存协程运行器，避免硬依赖EzMonoManager
    private static MonoBehaviour _coroutineRunner;

    /// <summary>
    /// 设置协程运行器（必须在使用异步方法前调用）
    /// </summary>
    public static void SetCoroutineRunner(MonoBehaviour runner)
    {
        _coroutineRunner = runner ?? throw new ArgumentNullException(nameof(runner), "协程运行器不能为null");
    }

    #region 物体查找
    /// <summary>
    /// 递归查找子物体（包含自身）
    /// </summary>
    public static GameObject FindChild(GameObject parent, string childName)
    {
        if (parent == null)
        {
            Debug.LogError("查找失败：父物体为null");
            return null;
        }

        if (parent.name == childName)
            return parent;

        foreach (Transform child in parent.transform)
        {
            GameObject found = FindChild(child.gameObject, childName);
            if (found != null)
                return found;
        }
        return null;
    }

    /// <summary>
    /// 获取所有子物体（包含嵌套子物体，不含自身）
    /// </summary>
    public static List<GameObject> GetAllChildren(Transform parent)
    {
        List<GameObject> children = new List<GameObject>();
        if (parent == null)
        {
            Debug.LogError("获取子物体失败：父Transform为null");
            return children;
        }

        GetChildrenRecursive(parent, children);
        return children;
    }

    // 递归收集子物体
    private static void GetChildrenRecursive(Transform parent, List<GameObject> list)
    {
        foreach (Transform child in parent)
        {
            list.Add(child.gameObject);
            GetChildrenRecursive(child, list); // 递归处理嵌套子物体
        }
    }
    #endregion

    #region 文件操作
    /// <summary>
    /// 读取文本文件内容
    /// </summary>
    public static string ReadTextFile(string path)
    {
        if (string.IsNullOrEmpty(path))
        {
            Debug.LogError("读取失败：文件路径为空");
            return null;
        }

        if (!File.Exists(path))
        {
            Debug.LogError($"读取失败：文件不存在 - {path}");
            return null;
        }

        try
        {
            // 使用using自动释放资源
            using (StreamReader reader = new StreamReader(path, Encoding.UTF8))
            {
                return reader.ReadToEnd();
            }
        }
        catch (Exception ex)
        {
            Debug.LogError($"读取文件异常：{ex.Message}，路径：{path}");
            return null;
        }
    }

    /// <summary>
    /// 写入文本到文件（支持移动端，建议使用Application.persistentDataPath路径）
    /// </summary>
    public static void WriteTextFile(string fullPath, string content, bool append = false)
    {
        if (string.IsNullOrEmpty(fullPath))
        {
            Debug.LogError("写入失败：文件路径为空");
            return;
        }

        try
        {
            // 确保目录存在
            string directory = Path.GetDirectoryName(fullPath);
            if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            // 根据append参数决定是覆盖还是追加
            FileMode mode = append ? FileMode.Append : FileMode.Create;
            using (FileStream fs = new FileStream(fullPath, mode, FileAccess.Write))
            using (StreamWriter writer = new StreamWriter(fs, Encoding.UTF8))
            {
                writer.Write(content); // 用Write而非WriteLine，避免自动添加换行
            }
            Debug.Log($"文件写入成功：{fullPath}");
        }
        catch (Exception ex)
        {
            Debug.LogError($"写入文件异常：{ex.Message}，路径：{fullPath}");
        }
    }

    /// <summary>
    /// 递归查找指定类型的文件
    /// </summary>
    public static List<string> FindFilesByType(string rootPath, string fileType)
    {
        List<string> result = new List<string>();
        if (string.IsNullOrEmpty(rootPath) || string.IsNullOrEmpty(fileType))
        {
            Debug.LogError("查找失败：路径或文件类型为空");
            return result;
        }

        if (!Directory.Exists(rootPath))
        {
            Debug.LogError($"查找失败：目录不存在 - {rootPath}");
            return result;
        }

        try
        {
            // 递归查找文件（忽略大小写）
            FindFilesRecursive(rootPath, fileType.TrimStart('.'), result);
        }
        catch (Exception ex)
        {
            Debug.LogError($"查找文件异常：{ex.Message}");
        }
        return result;
    }

    // 递归查找文件的实现
    private static void FindFilesRecursive(string currentPath, string targetExt, List<string> result)
    {
        // 获取当前目录所有文件
        foreach (string file in Directory.GetFiles(currentPath))
        {
            if (string.Equals(Path.GetExtension(file).TrimStart('.'), targetExt, StringComparison.OrdinalIgnoreCase))
            {
                result.Add(file);
            }
        }

        // 递归处理子目录
        foreach (string dir in Directory.GetDirectories(currentPath))
        {
            FindFilesRecursive(dir, targetExt, result);
        }
    }

    /// <summary>
    /// 查找或创建目录
    /// </summary>
    public static void EnsureDirectoryExists(string path)
    {
        if (string.IsNullOrEmpty(path))
        {
            Debug.LogError("目录路径为空");
            return;
        }

        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
            Debug.Log($"目录已创建：{path}");
        }
    }
    #endregion

    #region JSON操作
    /// <summary>
    /// 将对象序列化为JSON并保存到文件
    /// </summary>
    public static void SaveToJsonFile(object data, string fullPath)
    {
        if (data == null)
        {
            Debug.LogError("序列化失败：数据对象为null");
            return;
        }

        try
        {
            string json = JsonUtility.ToJson(data, true); // 格式化输出，便于阅读
            WriteTextFile(fullPath, json);
        }
        catch (Exception ex)
        {
            Debug.LogError($"JSON序列化失败：{ex.Message}");
        }
    }

    /// <summary>
    /// 从文件读取JSON并反序列化为对象
    /// </summary>
    public static T LoadFromJsonFile<T>(string fullPath) where T : class
    {
        string json = ReadTextFile(fullPath);
        if (string.IsNullOrEmpty(json))
            return null;

        try
        {
            return JsonUtility.FromJson<T>(json);
        }
        catch (Exception ex)
        {
            Debug.LogError($"JSON反序列化失败：{ex.Message}，路径：{fullPath}");
            return null;
        }
    }
    #endregion

    #region 事件系统
    /// <summary>
    /// 为物体添加EventTrigger事件
    /// </summary>
    public static void AddEventTriggerListener(GameObject obj, EventTriggerType eventType, UnityAction<BaseEventData> callback)
    {
        if (obj == null)
        {
            Debug.LogError("添加事件失败：物体为null");
            return;
        }

        if (callback == null)
        {
            Debug.LogError("添加事件失败：回调函数为null");
            return;
        }

        EventTrigger trigger = obj.GetComponent<EventTrigger>();
        if (trigger == null)
        {
            trigger = obj.AddComponent<EventTrigger>();
        }

        // 避免重复添加相同事件（可选逻辑，根据需求决定是否保留）
        foreach (var entry2 in trigger.triggers)
        {
            if (entry2.eventID == eventType)
            {
                Debug.LogWarning($"物体 {obj.name} 已存在 {eventType} 事件，将覆盖原有回调");
                entry2.callback.RemoveAllListeners();
                entry2.callback.AddListener(callback);
                return;
            }
        }

        // 添加新事件
        EventTrigger.Entry entry = new EventTrigger.Entry
        {
            eventID = eventType
        };
        entry.callback.AddListener(callback);
        trigger.triggers.Add(entry);
    }

    /// <summary>
    /// 判断鼠标是否在UI上
    /// </summary>
    public static bool IsMouseOverUI(GraphicRaycaster raycaster)
    {
        if (raycaster == null)
        {
            Debug.LogError("GraphicRaycaster为null，无法检测UI");
            return false;
        }

        if (EventSystem.current == null)
        {
            Debug.LogError("场景中没有EventSystem，无法检测UI");
            return false;
        }

        PointerEventData data = new PointerEventData(EventSystem.current)
        {
            position = Input.mousePosition
        };

        List<RaycastResult> results = new List<RaycastResult>();
        raycaster.Raycast(data, results);
        return results.Count > 0;
    }
    #endregion

    #region 工具方法
    /// <summary>
    /// 获取文件的MD5哈希值
    /// </summary>
    public static string GetFileMD5(string filePath)
    {
        if (string.IsNullOrEmpty(filePath))
        {
            Debug.LogError("MD5计算失败：文件路径为空");
            return null;
        }

        if (!File.Exists(filePath))
        {
            Debug.LogError($"MD5计算失败：文件不存在 - {filePath}");
            return null;
        }

        const int bufferSize = 1024 * 1024; // 1MB缓冲区
        using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
        using (MD5 md5 = MD5.Create())
        {
            byte[] buffer = new byte[bufferSize];
            int bytesRead;

            // 分块处理大文件
            while ((bytesRead = fs.Read(buffer, 0, bufferSize)) > 0)
            {
                // 最后一块用TransformFinalBlock，其他用TransformBlock
                if (bytesRead < bufferSize && fs.Position == fs.Length)
                {
                    md5.TransformFinalBlock(buffer, 0, bytesRead);
                }
                else
                {
                    md5.TransformBlock(buffer, 0, bytesRead, null, 0);
                }
            }

            // 转换为16进制字符串
            StringBuilder sb = new StringBuilder();
            foreach (byte b in md5.Hash)
            {
                sb.Append(b.ToString("x2")); // 小写x2确保32位长度
            }
            return sb.ToString();
        }
    }

    /// <summary>
    /// 运行外部程序
    /// </summary>
    public static void RunExternalProcess(string processPath, string arguments = "")
    {
        if (string.IsNullOrEmpty(processPath))
        {
            Debug.LogError("运行程序失败：路径为空");
            return;
        }

        if (!File.Exists(processPath))
        {
            Debug.LogError($"运行程序失败：文件不存在 - {processPath}");
            return;
        }

        try
        {
            Process.Start(new ProcessStartInfo
            {
                FileName = processPath,
                Arguments = arguments,
                UseShellExecute = true // 允许在不同平台上正确启动
            });
        }
        catch (Exception ex)
        {
            Debug.LogError($"运行程序异常：{ex.Message}，路径：{processPath}");
        }
    }

    /// <summary>
    /// 延迟执行方法
    /// </summary>
    public static void DelayExecute(float delaySeconds, UnityAction callback)
    {
        if (_coroutineRunner == null)
        {
            throw new InvalidOperationException("请先调用SetCoroutineRunner设置协程运行器");
        }
        if (callback == null)
        {
            Debug.LogError("延迟执行失败：回调函数为null");
            return;
        }
        _coroutineRunner.StartCoroutine(DelayCoroutine(delaySeconds, callback));
    }

    private static IEnumerator DelayCoroutine(float delay, UnityAction callback)
    {
        yield return new WaitForSeconds(delay);
        callback?.Invoke();
    }

    /// <summary>
    /// 安全销毁对象并尝试释放资源
    /// </summary>
    public static void SafeDestroy(UnityEngine.Object obj)
    {
        if (obj == null) return;

        if (Application.isPlaying)
        {
            UnityEngine.Object.Destroy(obj);
        }
        else
        {
            UnityEngine.Object.DestroyImmediate(obj); // 编辑模式下使用DestroyImmediate
        }
    }
    #endregion
}